//package org.poi;
//
//import lombok.AllArgsConstructor;
//import lombok.Data;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.poi.hssf.usermodel.HSSFWorkbook;
//import org.apache.poi.ss.usermodel.*;
//import org.apache.poi.ss.util.CellRangeAddress;
//import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
//import org.apache.poi.xssf.usermodel.XSSFRow;
//import org.apache.poi.xssf.usermodel.XSSFWorkbook;
//
//import java.io.*;
//import java.text.DateFormat;
//import java.text.NumberFormat;
//import java.text.SimpleDateFormat;
//import java.util.*;
//
///**
// * 请补充描述信息
// *
// * @author <a href="mailto:panpan.chen@vtradex.com">陈盼盼</a>
// * @version v1.0
// * @since 2023/12/29 23:46
// **/
//@Slf4j
//public class PoiExcelUtil {
//    private static final String EXCEL_XLS = "xls";
//    private static final String EXCEL_XLSX = "xlsx";
//
//    /**
//     * 读取excel文件中的全部表格
//     * 描述：适用于没有单元格合并的excel，并且 (titleOfRow,titleOfColumn)位置为读取内容的起始位置的情况
//     * 每一行构成一个map，key值是列标题，value是列值。没有值的单元格其value值为null
//     * 返回结果最外层list对应excel文件，第二层Iterable对应sheet页，第三层map对应sheet页中一行
//     *
//     * @param filePath 文件路径
//     * @param sheetCnt 读取的文件中前sheetCnt个sheet数据。如果值为-1，则读取所有的sheet，否则，读取前sheetCnt个sheet的数据。
//     * @return
//     * @throws Exception
//     */
//    public static List<List<Map<String, Object>>> readExcelWithFiexPos(String filePath, int titleInRow, int titleInColumn, int sheetCnt) throws IOException {
//        Workbook wb = null;
//        try {
//            List<List<Map<String, Object>>> excelData = new ArrayList<>();
//            if (filePath.endsWith(EXCEL_XLS) || filePath.endsWith(EXCEL_XLSX)) {
//                File file = new File(filePath);
//                wb = getWorkbook(file);
//                int sheetSize = sheetCnt == -1 ? wb.getNumberOfSheets() : sheetCnt;
//                //遍历sheet
//                for (int i = 0; i < sheetSize; i++) {
//                    Sheet sheet = wb.getSheetAt(i);
//                    List<Map<String, Object>> theSheetData = readSheet(sheet, titleInRow, titleInColumn);
//                    excelData.add(theSheetData);
//                }
//            } else {
//                log.error("读取的不是Excel文件");
//            }
//            return excelData;
//        } catch (FileNotFoundException e) {
//            throw e;
//        } finally {
//            if (wb != null) {
//                wb.close();
//            }
//        }
//    }
//
//    /**
//     * 读取excel文件中的全部表格
//     * 描述：适用于没有单元格合并的excel，并且 以fiexedValue在sheet中的位置为读取内容起始位置的情况
//     * 每一行构成一个map，key值是列标题，value是列值。没有值的单元格其value值为null
//     * 返回结果最外层list对应excel文件，第二层Iterable对应sheet页，第三层map对应sheet页中一行
//     *
//     * @param fixedValue 固定值（第一个列标题）
//     * @param filePath   文件路径
//     * @param sheetCnt   读取的文件中前sheetCnt个sheet数据。如果值为-1，则读取所有的sheet，否则，读取前sheetCnt个sheet的数据。
//     * @return
//     * @throws Exception
//     */
//    public static List<List<Map<String, Object>>> readExcelWithFiexedTitle(String filePath, String fixedValue, int sheetCnt) throws IOException {
//        Workbook wb = null;
//        try {
//            List<List<Map<String, Object>>> excelData = new ArrayList<>();
//            if (filePath.endsWith(EXCEL_XLS) || filePath.endsWith(EXCEL_XLSX)) {
//                File file = new File(filePath);
//                wb = getWorkbook(file);
//                int sheetSize = sheetCnt == -1 ? wb.getNumberOfSheets() : sheetCnt;
//                //遍历sheet
//                for (int i = 0; i < sheetSize; i++) {
//                    Sheet sheet = wb.getSheetAt(i);
//                    List<Integer> posForSheet = readPosForValue(sheet, fixedValue);
//                    List<Map<String, Object>> theSheetData = readSheet(sheet, posForSheet.get(0), posForSheet.get(1));
//                    excelData.add(theSheetData);
//                }
//            } else {
//                log.error("读取的不是Excel文件");
//            }
//            return excelData;
//        } catch (FileNotFoundException e) {
//            throw e;
//        } finally {
//            if (wb != null) {
//                wb.close();
//            }
//        }
//    }
//
//    /**
//     * 读取excel文件个sheet第rowNum行的内容，从firstColNum列开始往后读取到第lastColNum列
//     *
//     * @param filePath
//     * @param rowNum
//     * @param firstColNum
//     * @param lastColNum
//     * @return
//     */
//    public static List<List<Object>> readRowData(String filePath, int rowNum, int firstColNum, int lastColNum) throws IOException {
//        List<List<Object>> dataList = new ArrayList<>();
//
//        File file = new File(filePath);
//        Workbook wb = getWorkbook(file);
//        int sheetCnt = wb.getNumberOfSheets();
//
//        for (int cnt = 0; cnt < sheetCnt; cnt++) { //遍历每一个sheet
//            Sheet sheet = wb.getSheetAt(cnt);
//            Row row = sheet.getRow(rowNum);
//            lastColNum = lastColNum == -1 ? row.getLastCellNum() : lastColNum; //如果没有lastColNum则为其值为最后一列
//
//            List<Object> sheetContentList = new ArrayList<>();
//            Cell cell = null;
//            String value = null;
//            for (int i = firstColNum; i < lastColNum; i++) { //读取指定行的内容
//                cell = row.getCell(i);
//                value = readCellByType(cell);
//                sheetContentList.add(value);
//            }
//            dataList.add(sheetContentList);
//
//        }
//
//        return dataList;
//    }
//
//    /**
//     * 读取给定sheet的内容
//     * 描述：
//     * 读取excel文件中的指定名称的表格 用于没有单元格合并的表格，且 (titleOfRow,titleOfColumn)位置为读取内容的起始位置的情况
//     * 每一行构成一个map(key值是列标题，value是列值)。没有值的单元格其value值为null。
//     * 返回结果最外层的list对应一个sheet页，第二层的map对应sheet页中的一行。
//     *
//     * @param sheet
//     * @return
//     */
//    private static List<Map<String, Object>> readSheet(Sheet sheet, int titleInRow, int titleInColumn) {
//        List<Map<String, Object>> sheetList = null;
//        sheetList = new ArrayList<Map<String, Object>>();
//        List<String> titles = new ArrayList<>();
//        int rowSize = sheet.getLastRowNum() + 1;
//        for (int i = titleInRow; i < rowSize; i++) {
//            Row row = sheet.getRow(i);
//            if (row == null)
//                continue;
//            ;//略过空行
//            int cellSize = row.getLastCellNum();
//            if (i == titleInRow) //标题行
//            {
//                for (int j = titleInColumn; j < cellSize; j++) {
//                    Cell cell = row.getCell(j);
//                    if (cell != null) {
//                        titles.add(cell.toString());
//                    }
//                }
//            } else { //对应每一行的数据
//                Map<String, Object> rowDataMap = new LinkedHashMap<>();
//                for (int j = titleInColumn; j < titleInColumn + titles.size(); j++) {
//                    Cell cell = row.getCell(j);
//                    String value = null;
//                    CellType cellType = null;
//                    if (cell == null) {
//                        continue;
//                    }
//                    cellType = cell.getCellType();
//                    switch (cellType) {
//                        case STRING:
////                                 value = cell.getRichStringCellValue().getString();
//                            value = cell.getStringCellValue();
//                            break;
//                        case NUMERIC: //包含日期和普通数字
//                            if (DateUtil.isCellDateFormatted(cell)) {
//                                Date date = cell.getDateCellValue();
//                                DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
//                                value = df.format(date);
//                            } else {
//                                double cellValue = cell.getNumericCellValue();
//                                value = String.valueOf(cellValue);
//                                // 下面的代码，会自动舍弃读取单元格中显示的值（可能是做了round（）之后的结果），不是单元格中最原本的值
//                                /*NumberFormat nf = NumberFormat.getInstance();
//                                String tmpValue = nf.format(cell.getNumericCellValue());
//                                if (tmpValue.indexOf(",") >= 0) {
//                                    tmpValue = tmpValue.replaceAll(",", "");
//                                }
//                                value = tmpValue;*/
//
//                            }
//                            break;
//                        case FORMULA:
////                                 cell.getCellFormula();
//                            cell.setCellType(CellType.STRING);
//                            value = cell.getStringCellValue();
//                            break;
//                        case BOOLEAN:
//                            value = String.valueOf(cell.getBooleanCellValue());
//                            break;
//                        default:
//                            if (cell != null) {
//                                value = cell.toString();
//                            }
//                    }
//                    String key = titles.get(j - titleInColumn);
//                    rowDataMap.put(key, value);
//                }
//                sheetList.add(rowDataMap);
//            }
//        }
//        return sheetList;
//    }
//
//    /**
//     * 读取sheet中指定值的位置
//     *
//     * @param sheet
//     * @return
//     */
//    private static List<Integer> readPosForValue(Sheet sheet, String fixedValue) {
//        List<Integer> posList = new ArrayList();
//        Object value = null;
//        for (int j = 0; j < sheet.getPhysicalNumberOfRows(); j++) { // 获取每行
//            XSSFRow row = (XSSFRow) sheet.getRow(j);
//            if (row != null) {
//                for (int k = 0; k < sheet.getRow(0).getPhysicalNumberOfCells(); k++) { // 获取每个单元格
//                    Cell cell = row.getCell(k);
//                    if (cell == null) {
//                        continue;
//                    }
//                    CellType cellTypeEnum = cell.getCellType();
//                    switch (cellTypeEnum) {
//                        case STRING:
//                            value = cell.getRichStringCellValue().getString();
//                            break;
////                        case Cell.CELL_TYPE_NUMERIC:
//                        case NUMERIC:
//                            if (DateUtil.isCellDateFormatted(cell)) {
//                                value = cell.getDateCellValue();
//                            } else {
//                                double cellValue = cell.getNumericCellValue();
//                                value = String.valueOf(cellValue);
//                               /* // 下面的代码，会自动舍弃读取单元格中显示的值（可能是做了round（）之后的结果），不是单元格中最原本的值
//                                NumberFormat nf = NumberFormat.getInstance();
//                                String tmpValue = nf.format(cell.getNumericCellValue());
//                                if (tmpValue.indexOf(",") >= 0) {
//                                    tmpValue = tmpValue.replaceAll(",", "");
//                                }
//                                value = tmpValue;*/
//                            }
//                            break;
//                        case BOOLEAN:
//                            value = cell.getBooleanCellValue();
//                            break;
//                        case FORMULA:
//                            value = cell.getCellFormula();
//                            break;
//                        default:
//                            value = "";
//                            break;
//                    }
//                    if (fixedValue.equals(value.toString())) {
//                        posList.add(cell.getRowIndex());
//                        posList.add(cell.getColumnIndex());
//                        break;
//                    }
//                }
//            }
//            if (!posList.isEmpty()) {
//                break;
//            }
//        }
//        return posList;
//    }
//
//    /**
//     * 根据excel的版本，获取相应的Workbook
//     *
//     * @param file
//     * @return
//     */
//    public static Workbook getWorkbook(File file) throws IOException {
//        Workbook wb = null;
//        InputStream fis = new FileInputStream(file);
//        if (file.getName().endsWith(EXCEL_XLS)) //2003
//        {
//            wb = new HSSFWorkbook(fis);
//        } else if (file.getName().endsWith(EXCEL_XLSX)) {
//            wb = new XSSFWorkbook(fis);//2007 2010
//        }
//        if (fis != null) {
//            fis.close();
//        }
//        return wb;
//    }
//
//    /**
//     * 判断指定的单元格是否是合并单元格
//     *
//     * @param sheet
//     * @param row    行下标
//     * @param column 列下标
//     * @return
//     */
//    public static boolean isMergedRegion(Sheet sheet, int row, int column) {
//        int sheetMergeCount = sheet.getNumMergedRegions();
//        for (int i = 0; i < sheetMergeCount; i++) {
//            CellRangeAddress range = sheet.getMergedRegion(i);
//            int firstColumn = range.getFirstColumn();
//            int lastColumn = range.getLastColumn();
//            int firstRow = range.getFirstRow();
//            int lastRow = range.getLastRow();
//            if (row >= firstRow && row <= lastRow) {
//                if (column >= firstColumn && column <= lastColumn) {
//                    return true;
//                }
//            }
//        }
//        return false;
//    }
//
//    /**
//     * 获取合并单元格的值
//     *
//     * @param sheet
//     * @param row
//     * @param column
//     * @return
//     */
//    public static String getMergedCellValue(Sheet sheet, int row, int column) {
//        String value = null;
//        int mergedCellCnt = sheet.getNumMergedRegions();
//        for (int i = 0; i < mergedCellCnt; i++) {
//            CellRangeAddress mergedCell = sheet.getMergedRegion(i);
//            int firstColumn_pos = mergedCell.getFirstColumn();
//            int lastColumn_pos = mergedCell.getLastColumn();
//            int firstRow_pos = mergedCell.getFirstRow();
//            int lastRow_pos = mergedCell.getLastRow();
//            if (row >= firstRow_pos && row <= lastRow_pos) {
//                if (column >= firstColumn_pos && column <= lastColumn_pos) {
//                    Row firstRow = sheet.getRow(firstRow_pos);
//                    Cell cell = firstRow.getCell(firstColumn_pos);
//                    if (cell == null) {
//                        continue;
//                    }
//                    CellType cellType = cell.getCellType();
//                    switch (cellType) {
//                        case STRING:
////                                 value = cell.getRichStringCellValue().getString();
//                            value = cell.getStringCellValue();
//                            break;
//                        case NUMERIC: //包含日期和普通数字
//                            if (DateUtil.isCellDateFormatted(cell)) {
//                                Date date = cell.getDateCellValue();
//                                DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
//                                value = df.format(date);
//                            } else {
//                                double cellValue = cell.getNumericCellValue();
//                                value = String.valueOf(cellValue);
//
//                         /*       下面的代码，会自动舍弃读取单元格中显示的值（可能是做了round（）之后的结果），不是单元格中最原本的值
//                                NumberFormat nf = NumberFormat.getInstance();
//                                String tmpValue = nf.format(cell.getNumericCellValue());
//                                if (tmpValue.indexOf(",") >= 0) {
//                                    tmpValue = tmpValue.replaceAll(",", "");
//                                }
//                                value = tmpValue;*/
//                            }
//                            break;
//                        case FORMULA:
////                                 cell.getCellFormula();
//                            cell.setCellType(CellType.STRING);
//                            value = cell.getStringCellValue();
//                            break;
//                        case BOOLEAN:
//                            value = String.valueOf(cell.getBooleanCellValue());
//                            break;
//                        default:
//                            if (cell != null) {
//                                value = cell.toString();
//                            }
//                    }
//                    return cell == null || value == null ? "" : value;
//                }
//            }
//
//        }
//
//        return null;
//    }
//
//    /**
//     * 读取单元格的类型
//     *
//     * @param cell
//     * @return
//     */
//    public static String readCellByType(Cell cell) {
//        if (cell == null) {
//            return null;
//        }
//        CellType cellType = cell.getCellType();
//        String value = null;
//        switch (cellType) {
//            case STRING:
////                                 value = cell.getRichStringCellValue().getString();
//                value = cell.getStringCellValue();
//                break;
//            case NUMERIC: //包含日期和普通数字
//                if (DateUtil.isCellDateFormatted(cell)) {
//                    Date date = cell.getDateCellValue();
//                    DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
//                    value = df.format(date);
//                } else {
//                    double cellValue = cell.getNumericCellValue();
//                    value = String.valueOf(cellValue);
//
//                 /* 下面的代码，会自动舍弃读取单元格中显示的值（可能是做了round（）之后的结果），不是单元格中最原本的值
//                    NumberFormat nf = NumberFormat.getInstance();
//                    String tmpValue = nf.format(cell.getNumericCellValue());
//                    if (tmpValue.indexOf(",") >= 0) {
//                        tmpValue = tmpValue.replaceAll(",", "");
//                    }
//                    value = tmpValue;*/
//                }
//                break;
//            case FORMULA:
////                                 cell.getCellFormula();
//                cell.setCellType(CellType.STRING);
//                value = cell.getStringCellValue();
//                break;
//            case BOOLEAN:
//                value = String.valueOf(cell.getBooleanCellValue());
//                break;
//            default:
//                if (cell != null) {
//                    value = cell.toString();
//                }
//        }
//        return cell == null || value == null ? "" : value;
//    }
//
//    /**
//     * 读取一个excel文件中所有的sheet名字列表
//     *
//     * @param filePath 文件路径
//     * @return
//     * @throws Exception
//     */
//    public static List<String> readSheetNames(String filePath) throws Exception {
//        Workbook wb = null;
//        List<String> sheetNames = new ArrayList<String>();
//        try {
//            if (filePath.endsWith(EXCEL_XLS) || filePath.endsWith(EXCEL_XLSX)) {
//                // 读取Excel文档
//                File file = new File(filePath);
//                wb = getWorkbook(file);
//                int sheetSize = wb.getNumberOfSheets();
//                // 遍历sheet页
//                for (int i = 0; i < sheetSize; i++) {
//                    Sheet sheet = wb.getSheetAt(i);
//                    sheetNames.add(sheet.getSheetName());
//                }
//            } else {
//                throw new RuntimeException("");
//            }
//            return sheetNames;
//
//        } catch (FileNotFoundException e) {
//            log.error(e.getMessage());
//            throw e;
//        } finally {
//            if (wb != null) {
//                wb.close();
//            }
//        }
//    }
//
//    /**
//     * 读取excel中所有sheet的标题
//     *
//     * @return
//     */
//    public static List<String> readSheetTitles(String filePath) throws Exception {
//        Workbook wb = null;
//        List<String> titleList = new ArrayList<String>();
//        try {
//            if (filePath.endsWith(EXCEL_XLS) || filePath.endsWith(EXCEL_XLSX)) {
//                // 读取Excel文档
//                File file = new File(filePath);
//                wb = getWorkbook(file);
//                int sheetSize = wb.getNumberOfSheets();
//                for (int i = 0; i < sheetSize; i++) {
//                    Sheet sheet = wb.getSheetAt(i);
//                    Row row = sheet.getRow(0);//默认第一行为表头
//                    short lastCellNum = row.getLastCellNum();//共有多少列
//                    for (int j = 0; j < lastCellNum; j++) {
//                        Cell cell = row.getCell(j);
//                        titleList.add(cell.getStringCellValue().trim());
//                    }
//                }
//            }
//            return titleList;
//
//        } catch (Exception e) {
//            log.error(e.getMessage());
//            throw e;
//        } finally {
//            if (wb != null) {
//                wb.close();
//            }
//        }
//    }
//
//    public static Map<String, List<List<String>>> readExcel(File file) throws IOException {
//        Map<String, List<List<String>>> sheetRowValList = new HashMap<>();
//        Workbook workbook = workbook(file);
//        XSSFFormulaEvaluator formulaEvaluator = PoiExcelUtil.formulaEvaluator(workbook);
//        for (int x = 0; x < workbook.getNumberOfSheets(); x++) {
//            Sheet sheet = workbook.getSheetAt(x);
//            sheetRowValList.put(sheet.getSheetName(), realSheetVal(sheet, formulaEvaluator));
//        }
//        workbook.close();
//        return sheetRowValList;
//    }
//
//    public static List<List<String>> readExcelSheet(File file, String sheetName) throws IOException {
//        Workbook workbook = workbook(file);
//        XSSFFormulaEvaluator formulaEvaluator = PoiExcelUtil.formulaEvaluator(workbook);
//        Sheet sheet = workbook.getSheet(sheetName);
//        List<List<String>> lists = realSheetVal(sheet, formulaEvaluator);
//        workbook.close();
//        return lists;
//    }
//
//    private static List<List<String>> realSheetVal(Sheet sheet, XSSFFormulaEvaluator formulaEvaluator) {
//        List<List<String>> rowValList = new ArrayList<>();
//        List<MergedRegionValue> mergedRegionValues = getMergedRegionValues(sheet, formulaEvaluator);
//        int rows = sheet.getPhysicalNumberOfRows();
//        for (int r = 0; r < rows; r++) {
//            List<String> cellValList = new ArrayList<>();
//            Row row = sheet.getRow(r);
//            for (int c = 0; c < row.getPhysicalNumberOfCells(); c++) {
//                String cellValue = stringCellValue(row.getCell(c), formulaEvaluator);
//                if (cellValue.length() == 0) {
//                    cellValue = getMergedRegionValue(r, c, mergedRegionValues);
//                }
//                cellValList.add(cellValue);
//            }
//            rowValList.add(cellValList);
//        }
//        return rowValList;
//    }
//
//    public static String stringCellValue(Cell cell, FormulaEvaluator formulaEvaluator) {
//        if (cell == null) {
//            return "";
//        }
//        String regEx = "[\n\t]";
//        switch (cell.getCellType().name()) {
//            case "STRING":
//                return cell.getStringCellValue().replaceAll(regEx, "").trim();
//            case "NUMERIC":
//                NumberFormat numberFormat = NumberFormat.getInstance();
//                numberFormat.setGroupingUsed(false);
//                return numberFormat.format(cell.getNumericCellValue()).replaceAll(regEx, "").trim();
//            case "BOOLEAN":
//                return String.valueOf(cell.getBooleanCellValue()).replaceAll(regEx, "").trim();
//            case "FORMULA":
//                CellValue evaluate = formulaEvaluator.evaluate(cell);
//                return evaluate.formatAsString().replaceAll(regEx, "").trim();
//            default:
//                return "";
//        }
//    }
//
//    public static Workbook workbook(File file) throws IOException {
//        FileInputStream fileInputStream = new FileInputStream(file);
//        return Objects.requireNonNull(file.getName()).endsWith(".xlsx") ? new XSSFWorkbook(fileInputStream) :
//                new HSSFWorkbook(fileInputStream);
//    }
//
//    public static XSSFFormulaEvaluator formulaEvaluator(Workbook workbook) {
//        return new XSSFFormulaEvaluator((XSSFWorkbook) workbook);
//    }
//
//    /**
//     * 获取合并单元格的值
//     *
//     * @param sheet
//     * @param formulaEvaluator
//     * @return
//     */
//    public static List<MergedRegionValue> getMergedRegionValues(Sheet sheet, FormulaEvaluator formulaEvaluator) {
//        List<MergedRegionValue> mergedRegionValues = new ArrayList<>();
//        int sheetMergeCount = sheet.getNumMergedRegions();
//        for (int i = 0; i < sheetMergeCount; i++) {
//            CellRangeAddress ca = sheet.getMergedRegion(i);
//            int firstColumn = ca.getFirstColumn();
//            int lastColumn = ca.getLastColumn();
//            int firstRow = ca.getFirstRow();
//            int lastRow = ca.getLastRow();
//            Row fRow = sheet.getRow(firstRow);
//            Cell fCell = fRow.getCell(firstColumn);
//            String value = stringCellValue(fCell, formulaEvaluator);
//            mergedRegionValues.add(new MergedRegionValue(firstColumn, lastColumn, firstRow, lastRow, value));
//        }
//        return mergedRegionValues;
//    }
//
//    /**
//     * 获取合并单元格的值
//     *
//     * @param row
//     * @param column
//     * @param mergedRegionValues
//     * @return
//     */
//    public static String getMergedRegionValue(int row, int column, List<MergedRegionValue> mergedRegionValues) {
//        for (MergedRegionValue item : mergedRegionValues) {
//            if (row >= item.getFirstRow() && row <= item.getLastRow() &&
//                    column >= item.getFirstColumn() && column <= item.getLastColumn()) {
//                return item.getValue();
//            }
//        }
//        return "";
//    }
//
//    @Data
//    @AllArgsConstructor
//    public static class MergedRegionValue {
//        private int firstColumn;
//        private int lastColumn;
//        private int firstRow;
//        private int lastRow;
//        private String value;
//    }
//
//}
